home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / advqcc.zip / QCC.C < prev    next >
C/C++ Source or Header  |  1996-09-26  |  25KB  |  1,153 lines

  1.  
  2. #include "qcc.h"
  3. #include <time.h>
  4.  
  5. char        destfile[1024];
  6.  
  7. float        pr_globals[MAX_REGS];
  8. int            numpr_globals;
  9.  
  10. char        strings[MAX_STRINGS];
  11. int            strofs;
  12.  
  13. dstatement_t    statements[MAX_STATEMENTS];
  14. int            numstatements;
  15. int            statement_linenums[MAX_STATEMENTS];
  16.  
  17. dfunction_t    functions[MAX_FUNCTIONS];
  18. int            numfunctions;
  19.  
  20. ddef_t        globals[MAX_GLOBALS];
  21. int            numglobaldefs;
  22.  
  23. ddef_t        fields[MAX_FIELDS];
  24. int            numfielddefs;
  25.  
  26. char        precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
  27. int            precache_sounds_block[MAX_SOUNDS];
  28. int            numsounds;
  29.  
  30. char        precache_models[MAX_MODELS][MAX_DATA_PATH];
  31. int            precache_models_block[MAX_SOUNDS];
  32. int            nummodels;
  33.  
  34. char        precache_files[MAX_FILES][MAX_DATA_PATH];
  35. int            precache_files_block[MAX_SOUNDS];
  36. int            numfiles;
  37.  
  38.  
  39. /*
  40. =================
  41. BspModels
  42.  
  43. Runs qbsp and light on all of the models with a .bsp extension
  44. =================
  45. */
  46. void BspModels (void)
  47. {
  48.     int        p;
  49.     char    *gamedir;
  50.     int        i;
  51.     char    *m;
  52.     char    cmd[1024];
  53.     char    name[256];
  54.  
  55.     p = CheckParm ("-bspmodels");
  56.     if (!p)
  57.         return;
  58.     if (p == myargc-1)
  59.         Error ("-bspmodels must preceed a game directory");
  60.     gamedir = myargv[p+1];
  61.     
  62.     for (i=0 ; i<nummodels ; i++)
  63.     {
  64.         m = precache_models[i];
  65.         if (strcmp(m+strlen(m)-4, ".bsp"))
  66.             continue;
  67.         strcpy (name, m);
  68.         name[strlen(m)-4] = 0;
  69.         sprintf (cmd, "qbsp %s/%s ; light -extra %s/%s", gamedir, name, gamedir, name);
  70.         system (cmd);
  71.     }
  72. }
  73.  
  74. // CopyString returns an offset from the string heap
  75. int    CopyString (char *str)
  76. {
  77.     int        old;
  78.     
  79.     old = strofs;
  80.     strcpy (strings+strofs, str);
  81.     strofs += strlen(str)+1;
  82.     return old;
  83. }
  84.  
  85. void PrintStrings (void)
  86. {
  87.     int        i, l, j;
  88.     
  89.     for (i=0 ; i<strofs ; i += l)
  90.     {
  91.         l = strlen(strings+i) + 1;
  92.         printf ("%5i : ",i);
  93.         for (j=0 ; j<l ; j++)
  94.         {
  95.             if (strings[i+j] == '\n')
  96.             {
  97.                 putchar ('\\');
  98.                 putchar ('n');
  99.             }
  100.             else
  101.                 putchar (strings[i+j]);
  102.         }
  103.         printf ("\n");
  104.     }
  105. }
  106.  
  107.  
  108. void PrintFunctions (void)
  109. {
  110.     int        i,j;
  111.     dfunction_t    *d;
  112.     
  113.     for (i=0 ; i<numfunctions ; i++)
  114.     {
  115.         d = &functions[i];
  116.         printf ("%s : %s : %i %i (", strings + d->s_file, strings + d->s_name, d->first_statement, d->parm_start);
  117.         for (j=0 ; j<d->numparms ; j++)
  118.             printf ("%i ",d->parm_size[j]);
  119.         printf (")\n");
  120.     }
  121. }
  122.  
  123. void PrintFields (void)
  124. {
  125.     int        i;
  126.     ddef_t    *d;
  127.     
  128.     for (i=0 ; i<numfielddefs ; i++)
  129.     {
  130.         d = &fields[i];
  131.         printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  132.     }
  133. }
  134.  
  135. void PrintGlobals (void)
  136. {
  137.     int        i;
  138.     ddef_t    *d;
  139.     
  140.     for (i=0 ; i<numglobaldefs ; i++)
  141.     {
  142.         d = &globals[i];
  143.         printf ("%5i : (%i) %s\n", d->ofs, d->type, strings + d->s_name);
  144.     }
  145. }
  146.  
  147.  
  148. void InitData (void)
  149. {
  150.     int        i;
  151.     
  152.     numstatements = 1;
  153.     strofs = 1;
  154.     numfunctions = 1;
  155.     numglobaldefs = 1;
  156.     numfielddefs = 1;
  157.     
  158.     def_ret.ofs = OFS_RETURN;
  159.     for (i=0 ; i<MAX_PARMS ; i++)
  160.         def_parms[i].ofs = OFS_PARM0 + 3*i;
  161. }
  162.  
  163.  
  164. void WriteData (int crc)
  165. {
  166.     def_t        *def;
  167.     ddef_t        *dd;
  168.     dprograms_t    progs;
  169.     int            h;
  170.     int            i;
  171.  
  172.     for (def = pr.def_head; def; def = def->next)
  173.     {
  174.         if (def->type->type == ev_function)
  175.         {
  176. //            df = &functions[numfunctions];
  177. //            numfunctions++;
  178.  
  179.         }
  180.         else if (def->type->type == ev_field)
  181.         {
  182.             dd = &fields[numfielddefs];
  183.             numfielddefs++;
  184.             dd->type = def->type->aux_type->type;
  185.             dd->s_name = CopyString (def->name);
  186.             dd->ofs = G_INT(def->ofs);
  187.         }
  188.         dd = &globals[numglobaldefs];
  189.         numglobaldefs++;
  190.         dd->type = def->type->type;
  191.         if ( !def->initialized
  192.         && def->type->type != ev_function
  193.         && def->type->type != ev_field
  194.         && def->scope == NULL)
  195.             dd->type |= DEF_SAVEGLOBGAL;
  196.         dd->s_name = CopyString (def->name);
  197.         dd->ofs = def->ofs;
  198.     }
  199.  
  200. //PrintStrings ();
  201. //PrintFunctions ();
  202. //PrintFields ();
  203. //PrintGlobals ();
  204. strofs = (strofs+3)&~3;
  205.  
  206.     printf ("%6i strofs\n", strofs);
  207.     printf ("%6i numstatements\n", numstatements);
  208.     printf ("%6i numfunctions\n", numfunctions);
  209.     printf ("%6i numglobaldefs\n", numglobaldefs);
  210.     printf ("%6i numfielddefs\n", numfielddefs);
  211.     printf ("%6i numpr_globals\n", numpr_globals);
  212.  
  213.     h = SafeOpenWrite (destfile);
  214.     SafeWrite (h, &progs, sizeof(progs));
  215.  
  216.     progs.ofs_strings = lseek (h, 0, SEEK_CUR);
  217.     progs.numstrings = strofs;
  218.     SafeWrite (h, strings, strofs);
  219.  
  220.     progs.ofs_statements = lseek (h, 0, SEEK_CUR);
  221.     progs.numstatements = numstatements;
  222.     for (i=0 ; i<numstatements ; i++)
  223.     {
  224.         statements[i].op = LittleShort(statements[i].op);
  225.         statements[i].a = LittleShort(statements[i].a);
  226.         statements[i].b = LittleShort(statements[i].b);
  227.         statements[i].c = LittleShort(statements[i].c);
  228.     }
  229.     SafeWrite (h, statements, numstatements*sizeof(dstatement_t));
  230.  
  231.     progs.ofs_functions = lseek (h, 0, SEEK_CUR);
  232.     progs.numfunctions = numfunctions;
  233.     for (i=0 ; i<numfunctions ; i++)
  234.     {
  235.     functions[i].first_statement = LittleLong (functions[i].first_statement);
  236.     functions[i].parm_start = LittleLong (functions[i].parm_start);
  237.     functions[i].s_name = LittleLong (functions[i].s_name);
  238.     functions[i].s_file = LittleLong (functions[i].s_file);
  239.     functions[i].numparms = LittleLong (functions[i].numparms);
  240.     functions[i].locals = LittleLong (functions[i].locals);
  241.     }
  242.     SafeWrite (h, functions, numfunctions*sizeof(dfunction_t));
  243.  
  244.     progs.ofs_globaldefs = lseek (h, 0, SEEK_CUR);
  245.     progs.numglobaldefs = numglobaldefs;
  246.     for (i=0 ; i<numglobaldefs ; i++)
  247.     {
  248.         globals[i].type = LittleShort (globals[i].type);
  249.         globals[i].ofs = LittleShort (globals[i].ofs);
  250.         globals[i].s_name = LittleLong (globals[i].s_name);
  251.     }
  252.     SafeWrite (h, globals, numglobaldefs*sizeof(ddef_t));
  253.  
  254.     progs.ofs_fielddefs = lseek (h, 0, SEEK_CUR);
  255.     progs.numfielddefs = numfielddefs;
  256.     for (i=0 ; i<numfielddefs ; i++)
  257.     {
  258.         fields[i].type = LittleShort (fields[i].type);
  259.         fields[i].ofs = LittleShort (fields[i].ofs);
  260.         fields[i].s_name = LittleLong (fields[i].s_name);
  261.     }
  262.     SafeWrite (h, fields, numfielddefs*sizeof(ddef_t));
  263.  
  264.     progs.ofs_globals = lseek (h, 0, SEEK_CUR);
  265.     progs.numglobals = numpr_globals;
  266.     for (i=0 ; i<numpr_globals ; i++)
  267.         ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
  268.     SafeWrite (h, pr_globals, numpr_globals*4);
  269.  
  270.     printf ("%6i TOTAL SIZE\n", (int)lseek (h, 0, SEEK_CUR));    
  271.  
  272.     progs.entityfields = pr.size_fields;
  273.  
  274.     progs.version = PROG_VERSION;
  275.     progs.crc = crc;
  276.     
  277. // byte swap the header and write it out
  278.     for (i=0 ; i<sizeof(progs)/4 ; i++)
  279.         ((int *)&progs)[i] = LittleLong ( ((int *)&progs)[i] );        
  280.     lseek (h, 0, SEEK_SET);
  281.     SafeWrite (h, &progs, sizeof(progs));
  282.     close (h);
  283. }
  284.  
  285.  
  286.  
  287. /*
  288. ===============
  289. PR_String
  290.  
  291. Returns a string suitable for printing (no newlines, max 60 chars length)
  292. ===============
  293. */
  294. char *PR_String (char *string)
  295. {
  296.     static char buf[80];
  297.     char    *s;
  298.     
  299.     s = buf;
  300.     *s++ = '"';
  301.     while (string && *string)
  302.     {
  303.         if (s == buf + sizeof(buf) - 2)
  304.             break;
  305.         if (*string == '\n')
  306.         {
  307.             *s++ = '\\';
  308.             *s++ = 'n';
  309.         }
  310.         else if (*string == '"')
  311.         {
  312.             *s++ = '\\';
  313.             *s++ = '"';
  314.         }
  315.         else
  316.             *s++ = *string;
  317.         string++;
  318.         if (s - buf > 60)
  319.         {
  320.             *s++ = '.';
  321.             *s++ = '.';
  322.             *s++ = '.';
  323.             break;
  324.         }
  325.     }
  326.     *s++ = '"';
  327.     *s++ = 0;
  328.     return buf;
  329. }
  330.  
  331.  
  332.  
  333. def_t    *PR_DefForFieldOfs (gofs_t ofs)
  334. {
  335.     def_t    *d;
  336.     
  337.     for (d=pr.def_head; d ; d=d->next)
  338.     {
  339.         if (d->type->type != ev_field)
  340.             continue;
  341.         if (*((int *)&pr_globals[d->ofs]) == ofs)
  342.             return d;
  343.     }
  344.     Error ("PR_DefForFieldOfs: couldn't find %i",ofs);
  345.     return NULL;
  346. }
  347.  
  348. /*
  349. ============
  350. PR_ValueString
  351.  
  352. Returns a string describing *data in a type specific manner
  353. =============
  354. */
  355. char *PR_ValueString (etype_t type, void *val)
  356. {
  357.     static char    line[256];
  358.     def_t        *def;
  359.     dfunction_t    *f;
  360.     
  361.     switch (type)
  362.     {
  363.     case ev_string:
  364.         sprintf (line, "%s", PR_String(strings + *(int *)val));
  365.         break;
  366.     case ev_entity:    
  367.         sprintf (line, "entity %i", *(int *)val);
  368.         break;
  369.     case ev_function:
  370.         f = functions + *(int *)val;
  371.         if (!f)
  372.             sprintf (line, "undefined function");
  373.         else
  374.             sprintf (line, "%s()", strings + f->s_name);
  375.         break;
  376.     case ev_field:
  377.         def = PR_DefForFieldOfs ( *(int *)val );
  378.         sprintf (line, ".%s", def->name);
  379.         break;
  380.     case ev_void:
  381.         sprintf (line, "void");
  382.         break;
  383.     case ev_float:
  384.         sprintf (line, "%5.1f", *(float *)val);
  385.         break;
  386.     case ev_vector:
  387.         sprintf (line, "'%5.1f %5.1f %5.1f'", ((float *)val)[0], ((float *)val)[1], ((float *)val)[2]);
  388.         break;
  389.     case ev_pointer:
  390.         sprintf (line, "pointer");
  391.         break;
  392.     default:
  393.         sprintf (line, "bad type %i", type);
  394.         break;
  395.     }
  396.     
  397.     return line;
  398. }
  399.  
  400. /*
  401. ============
  402. PR_GlobalString
  403.  
  404. Returns a string with a description and the contents of a global,
  405. padded to 20 field width
  406. ============
  407. */
  408. char *PR_GlobalStringNoContents (gofs_t ofs)
  409. {
  410.     int        i;
  411.     def_t    *def;
  412. //    void    *val;
  413.     static char    line[128];
  414.  
  415. //    val = (void *)&pr_globals[ofs];
  416.     def = pr_global_defs[ofs];
  417.     if (!def)
  418. //        Error ("PR_GlobalString: no def for %i", ofs);
  419.         sprintf (line,"%i(???)", ofs);
  420.     else
  421.         sprintf (line,"%i(%s)", ofs, def->name);
  422.  
  423.     i = strlen(line);
  424.     for ( ; i<16 ; i++)
  425.         strcat (line," ");
  426.     strcat (line," ");
  427.  
  428.     return line;
  429. }
  430.  
  431. char *PR_GlobalString (gofs_t ofs)
  432. {
  433.     char    *s;
  434.     int        i;
  435.     def_t    *def;
  436. //    void    *val;
  437.     static char    line[128];
  438.  
  439. //    val = (void *)&pr_globals[ofs];
  440.     def = pr_global_defs[ofs];
  441.     if (!def)
  442.         return PR_GlobalStringNoContents(ofs);
  443.     if (def->initialized && def->type->type != ev_function)
  444.     {
  445.         s = PR_ValueString (def->type->type, &pr_globals[ofs]);
  446.         sprintf (line,"%i(%s)", ofs, s);
  447.     }
  448.     else
  449.         sprintf (line,"%i(%s)", ofs, def->name);
  450.     
  451.     i = strlen(line);
  452.     for ( ; i<16 ; i++)
  453.         strcat (line," ");
  454.     strcat (line," ");
  455.         
  456.     return line;
  457. }
  458.  
  459. /*
  460. ============
  461. PR_PrintOfs
  462. ============
  463. */
  464. void PR_PrintOfs (gofs_t ofs)
  465. {
  466.     printf ("%s\n",PR_GlobalString(ofs));
  467. }
  468.  
  469. /*
  470. =================
  471. PR_PrintStatement
  472. =================
  473. */
  474. void PR_PrintStatement (dstatement_t *s)
  475. {
  476.     int        i;
  477.     
  478.     printf ("%4i : %4i : %s ", (int)(s - statements), statement_linenums[s-statements], pr_opcodes[s->op].opname);
  479.     i = strlen(pr_opcodes[s->op].opname);
  480.     for ( ; i<10 ; i++)
  481.         printf (" ");
  482.         
  483.     if (s->op == OP_IF || s->op == OP_IFNOT)
  484.         printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
  485.     else if (s->op == OP_GOTO)
  486.     {
  487.         printf ("branch %i",s->a);
  488.     }
  489.     else if ( (unsigned)(s->op - OP_STORE_F) < 6)
  490.     {
  491.         printf ("%s",PR_GlobalString(s->a));
  492.         printf ("%s", PR_GlobalStringNoContents(s->b));
  493.     }
  494.     else
  495.     {
  496.         if (s->a)
  497.             printf ("%s",PR_GlobalString(s->a));
  498.         if (s->b)
  499.             printf ("%s",PR_GlobalString(s->b));
  500.         if (s->c)
  501.             printf ("%s", PR_GlobalStringNoContents(s->c));
  502.     }
  503.     printf ("\n");
  504. }
  505.  
  506.  
  507. /*
  508. ============
  509. PR_PrintDefs
  510. ============
  511. */
  512. void PR_PrintDefs (void)
  513. {
  514.     def_t    *d;
  515.     
  516.     for (d=pr.def_head; d ; d=d->next)
  517.         PR_PrintOfs (d->ofs);
  518. }
  519.  
  520.  
  521. /*
  522. ==============
  523. PR_BeginCompilation
  524.  
  525. called before compiling a batch of files, clears the pr struct
  526. ==============
  527. */
  528. void    PR_BeginCompilation (void *memory, int memsize)
  529. {
  530.     int        i;
  531.  
  532.     pr.memory = memory;
  533.     pr.max_memory = memsize;
  534.     
  535.     numpr_globals = RESERVED_OFS;
  536.     pr.def_head = NULL;
  537.  
  538.     for (i=0 ; i<RESERVED_OFS ; i++)
  539.         pr_global_defs[i] = &def_void;
  540.         
  541. // link the function type in so state forward declarations match proper type
  542.     pr.types = &type_function;
  543.     type_function.next = NULL;
  544.     pr_error_count = 0;
  545. }
  546.  
  547. /*
  548. ==============
  549. PR_FinishCompilation
  550.  
  551. called after all files are compiled to check for errors
  552. Returns false if errors were detected.
  553. ==============
  554. */
  555. boolean    PR_FinishCompilation (void)
  556. {
  557.     def_t        *d;
  558.     boolean    errors;
  559.     
  560.     errors = false;
  561.     
  562. // check to make sure all functions prototyped have code
  563.     for (d=pr.def_head; d ; d=d->next)
  564.     {
  565.         if (d->type->type == ev_function && !d->scope)// function parms are ok
  566.         {
  567. //            f = G_FUNCTION(d->ofs);
  568. //            if (!f || (!f->code && !f->builtin) )
  569.             if (!d->initialized)
  570.             {
  571.                 printf ("function %s was not defined\n",d->name);
  572.                 errors = true;
  573.             }
  574.         }
  575.     }
  576.  
  577.     return !errors;
  578. }
  579.  
  580. //=============================================================================
  581.  
  582. // FIXME: byte swap?
  583.  
  584. // this is a 16 bit, non-reflected CRC using the polynomial 0x1021
  585. // and the initial and final xor values shown below...  in other words, the
  586. // CCITT standard CRC used by XMODEM
  587.  
  588. #define CRC_INIT_VALUE    0xffff
  589. #define CRC_XOR_VALUE    0x0000
  590.  
  591. static unsigned short crctable[256] =
  592. {
  593.     0x0000,    0x1021,    0x2042,    0x3063,    0x4084,    0x50a5,    0x60c6,    0x70e7,
  594.     0x8108,    0x9129,    0xa14a,    0xb16b,    0xc18c,    0xd1ad,    0xe1ce,    0xf1ef,
  595.     0x1231,    0x0210,    0x3273,    0x2252,    0x52b5,    0x4294,    0x72f7,    0x62d6,
  596.     0x9339,    0x8318,    0xb37b,    0xa35a,    0xd3bd,    0xc39c,    0xf3ff,    0xe3de,
  597.     0x2462,    0x3443,    0x0420,    0x1401,    0x64e6,    0x74c7,    0x44a4,    0x5485,
  598.     0xa56a,    0xb54b,    0x8528,    0x9509,    0xe5ee,    0xf5cf,    0xc5ac,    0xd58d,
  599.     0x3653,    0x2672,    0x1611,    0x0630,    0x76d7,    0x66f6,    0x5695,    0x46b4,
  600.     0xb75b,    0xa77a,    0x9719,    0x8738,    0xf7df,    0xe7fe,    0xd79d,    0xc7bc,
  601.     0x48c4,    0x58e5,    0x6886,    0x78a7,    0x0840,    0x1861,    0x2802,    0x3823,
  602.     0xc9cc,    0xd9ed,    0xe98e,    0xf9af,    0x8948,    0x9969,    0xa90a,    0xb92b,
  603.     0x5af5,    0x4ad4,    0x7ab7,    0x6a96,    0x1a71,    0x0a50,    0x3a33,    0x2a12,
  604.     0xdbfd,    0xcbdc,    0xfbbf,    0xeb9e,    0x9b79,    0x8b58,    0xbb3b,    0xab1a,
  605.     0x6ca6,    0x7c87,    0x4ce4,    0x5cc5,    0x2c22,    0x3c03,    0x0c60,    0x1c41,
  606.     0xedae,    0xfd8f,    0xcdec,    0xddcd,    0xad2a,    0xbd0b,    0x8d68,    0x9d49,
  607.     0x7e97,    0x6eb6,    0x5ed5,    0x4ef4,    0x3e13,    0x2e32,    0x1e51,    0x0e70,
  608.     0xff9f,    0xefbe,    0xdfdd,    0xcffc,    0xbf1b,    0xaf3a,    0x9f59,    0x8f78,
  609.     0x9188,    0x81a9,    0xb1ca,    0xa1eb,    0xd10c,    0xc12d,    0xf14e,    0xe16f,
  610.     0x1080,    0x00a1,    0x30c2,    0x20e3,    0x5004,    0x4025,    0x7046,    0x6067,
  611.     0x83b9,    0x9398,    0xa3fb,    0xb3da,    0xc33d,    0xd31c,    0xe37f,    0xf35e,
  612.     0x02b1,    0x1290,    0x22f3,    0x32d2,    0x4235,    0x5214,    0x6277,    0x7256,
  613.     0xb5ea,    0xa5cb,    0x95a8,    0x8589,    0xf56e,    0xe54f,    0xd52c,    0xc50d,
  614.     0x34e2,    0x24c3,    0x14a0,    0x0481,    0x7466,    0x6447,    0x5424,    0x4405,
  615.     0xa7db,    0xb7fa,    0x8799,    0x97b8,    0xe75f,    0xf77e,    0xc71d,    0xd73c,
  616.     0x26d3,    0x36f2,    0x0691,    0x16b0,    0x6657,    0x7676,    0x4615,    0x5634,
  617.     0xd94c,    0xc96d,    0xf90e,    0xe92f,    0x99c8,    0x89e9,    0xb98a,    0xa9ab,
  618.     0x5844,    0x4865,    0x7806,    0x6827,    0x18c0,    0x08e1,    0x3882,    0x28a3,
  619.     0xcb7d,    0xdb5c,    0xeb3f,    0xfb1e,    0x8bf9,    0x9bd8,    0xabbb,    0xbb9a,
  620.     0x4a75,    0x5a54,    0x6a37,    0x7a16,    0x0af1,    0x1ad0,    0x2ab3,    0x3a92,
  621.     0xfd2e,    0xed0f,    0xdd6c,    0xcd4d,    0xbdaa,    0xad8b,    0x9de8,    0x8dc9,
  622.     0x7c26,    0x6c07,    0x5c64,    0x4c45,    0x3ca2,    0x2c83,    0x1ce0,    0x0cc1,
  623.     0xef1f,    0xff3e,    0xcf5d,    0xdf7c,    0xaf9b,    0xbfba,    0x8fd9,    0x9ff8,
  624.     0x6e17,    0x7e36,    0x4e55,    0x5e74,    0x2e93,    0x3eb2,    0x0ed1,    0x1ef0
  625. };
  626.  
  627. void CRC_Init(unsigned short *crcvalue)
  628. {
  629.     *crcvalue = CRC_INIT_VALUE;
  630. }
  631.  
  632. void CRC_ProcessByte(unsigned short *crcvalue, byte data)
  633. {
  634.     *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data];
  635. }
  636.  
  637. unsigned short CRC_Value(unsigned short crcvalue)
  638. {
  639.     return crcvalue ^ CRC_XOR_VALUE;
  640. }
  641. //=============================================================================
  642.  
  643. /*
  644. ============
  645. PR_WriteProgdefs
  646.  
  647. Writes the global and entity structures out
  648. Returns a crc of the header, to be stored in the progs file for comparison
  649. at load time.
  650. ============
  651. */
  652. int    PR_WriteProgdefs (char *filename)
  653. {
  654.   def_t *d;     
  655.     FILE    *f;
  656.     unsigned short        crc;
  657.     int        c;
  658.   int sub;
  659.   int len;
  660.  
  661.     printf ("writing %s\n", filename);
  662.     f = fopen (filename, "w");
  663.  
  664. // print global vars until the first field is defined
  665.     fprintf (f,"\n/* file generated by qcc, do not modify */\n\ntypedef struct\n{\tint\tpad[%i];\n", RESERVED_OFS);
  666.   sub = 0;
  667.   while (sub < numpr_globals)
  668.     {
  669.     d = pr_global_defs[sub];
  670.     if (d == NULL || strcmp(d->name, "IMMEDIATE") == 0)
  671.     {
  672.       sub++;
  673.       continue;
  674.     }
  675.         if (!strcmp (d->name, "end_sys_globals"))
  676.     {
  677.       sub++;
  678.             break;
  679.     }
  680.  
  681.     switch (d->type->type)
  682.         {
  683.         case ev_float:
  684.       len = strlen(d->name);
  685.       if (len < 3 || d->name[len - 1] != 'x' || d->name[len - 2] != '_')
  686.               fprintf (f, "\tfloat\t%s;\n",d->name);
  687.       else
  688.       {
  689.         len -= 2;
  690.         fprintf (f, "\tvec3_t\t%*.*s;\n", len, len, d->name);
  691.         sub += 2;
  692.       }
  693.           break;
  694.         case ev_vector:
  695.             fprintf (f, "\tvec3_t\t%s;\n",d->name);
  696.       sub += 3;
  697.             break;
  698.         case ev_string:
  699.             fprintf (f,"\tstring_t\t%s;\n",d->name);
  700.             break;
  701.         case ev_function:
  702.             fprintf (f,"\tfunc_t\t%s;\n",d->name);
  703.             break;
  704.         case ev_entity:
  705.             fprintf (f,"\tint\t%s;\n",d->name);
  706.             break;
  707.         default:
  708.             break;
  709.         }
  710.     sub++;
  711.     }
  712.     fprintf (f,"} globalvars_t;\n\n");
  713.  
  714. // print all fields
  715.     fprintf (f,"typedef struct\n{\n");
  716. //  sub = 0;
  717.   while (sub < numpr_globals)
  718.     {
  719.     d = pr_global_defs[sub];
  720.     if (d == NULL || strcmp(d->name, "IMMEDIATE") == 0)
  721.     {
  722.       sub++;
  723.       continue;
  724.     }
  725.         if (!strcmp (d->name, "end_sys_fields"))
  726.             break;
  727.  
  728.         if (d->type->type != ev_field)
  729.             continue;
  730.  
  731.         switch (d->type->aux_type->type)
  732.         {
  733.         case ev_float:
  734. //      len = strlen(d->name);
  735. //      if (len < 3 || d->name[len - 1] != 'x' || d->name[len - 2] != '_')
  736.               fprintf (f, "\tfloat\t%s;\n",d->name);
  737. //      else
  738. //      {
  739. //        len -= 2;
  740. //        fprintf (f, "\tvec3_t\t%*.*s;\n", len, len, d->name);
  741. //        sub += 2;
  742. //      }
  743.           break;
  744.         case ev_vector:
  745.             fprintf (f, "\tvec3_t\t%s;\n",d->name);
  746.       sub += 3;
  747.             break;
  748.         case ev_string:
  749.             fprintf (f,"\tstring_t\t%s;\n",d->name);
  750.             break;
  751.         case ev_function:
  752.             fprintf (f,"\tfunc_t\t%s;\n",d->name);
  753.             break;
  754.         case ev_entity:
  755.             fprintf (f,"\tint\t%s;\n",d->name);
  756.             break;
  757.         default:
  758.             break;
  759.         }
  760.     sub++;
  761.     }
  762.     fprintf (f,"} entvars_t;\n\n");
  763.  
  764.     fclose (f);
  765.     
  766. // do a crc of the file
  767.     CRC_Init (&crc);
  768.     f = fopen (filename, "r+");
  769.     while ((c = fgetc(f)) != EOF)
  770.         CRC_ProcessByte (&crc, c);
  771.         
  772.     fprintf (f,"#define PROGHEADER_CRC %i\n", crc);
  773.     fclose (f);
  774.  
  775.     return crc;
  776. }
  777.  
  778.  
  779. void PrintFunction (char *name)
  780. {
  781.     int        i;
  782.     dstatement_t    *ds;
  783.     dfunction_t        *df;
  784.     
  785.     for (i=0 ; i<numfunctions ; i++)
  786.         if (!strcmp (name, strings + functions[i].s_name))
  787.             break;
  788.     if (i==numfunctions)
  789.         Error ("No function names \"%s\"", name);
  790.     df = functions + i;    
  791.     
  792.     printf ("Statements for %s:\n", name);
  793.     ds = statements + df->first_statement;
  794.     while (1)
  795.     {
  796.         PR_PrintStatement (ds);
  797.         if (!ds->op)
  798.             break;
  799.         ds++;
  800.     }
  801. }
  802.  
  803. /*
  804. ==============================================================================
  805.  
  806. DIRECTORY COPYING / PACKFILE CREATION
  807.  
  808. ==============================================================================
  809. */
  810.  
  811. typedef struct
  812. {
  813.     char    name[56];
  814.     int        filepos, filelen;
  815. } packfile_t;
  816.  
  817. typedef struct
  818. {
  819.     char    id[4];
  820.     int        dirofs;
  821.     int        dirlen;
  822. } packheader_t;
  823.  
  824. packfile_t    pfiles[4096], *pf;
  825. int            packhandle;
  826. int            packbytes;
  827.  
  828. void Sys_mkdir (char *path)
  829. {
  830.     if (mkdir (path, 0777) != -1)
  831.         return;
  832.     if (errno != EEXIST)
  833.         Error ("mkdir %s: %s",path, strerror(errno)); 
  834. }
  835.  
  836. /*
  837. ============
  838. CreatePath
  839. ============
  840. */
  841. void    CreatePath (char *path)
  842. {
  843.     char    *ofs;
  844.     
  845.     for (ofs = path+1 ; *ofs ; ofs++)
  846.     {
  847.         if (*ofs == '/')
  848.         {    // create the directory
  849.             *ofs = 0;
  850.             Sys_mkdir (path);
  851.             *ofs = '/';
  852.         }
  853.     }
  854. }
  855.  
  856.  
  857. /*
  858. ===========
  859. PackFile
  860.  
  861. Copy a file into the pak file
  862. ===========
  863. */
  864. void PackFile (char *src, char *name)
  865. {
  866.     int        in;
  867.     int        remaining, count;
  868.     char    buf[4096];
  869.     
  870.     if ( (byte *)pf - (byte *)pfiles > sizeof(pfiles) )
  871.         Error ("Too many files in pak file");
  872.     
  873.     in = SafeOpenRead (src);
  874.     remaining = filelength (in);
  875.  
  876.     pf->filepos = LittleLong (lseek (packhandle, 0, SEEK_CUR));
  877.     pf->filelen = LittleLong (remaining);
  878.     strcpy (pf->name, name);
  879.     printf ("%64s : %7i\n", pf->name, remaining);
  880.  
  881.     packbytes += remaining;
  882.     
  883.     while (remaining)
  884.     {
  885.         if (remaining < sizeof(buf))
  886.             count = remaining;
  887.         else
  888.             count = sizeof(buf);
  889.         SafeRead (in, buf, count);
  890.         SafeWrite (packhandle, buf, count);
  891.         remaining -= count;
  892.     }
  893.  
  894.     close (in);
  895.     pf++;
  896. }
  897.  
  898.  
  899. /*
  900. ===========
  901. CopyFile
  902.  
  903. Copies a file, creating any directories needed
  904. ===========
  905. */
  906. void CopyFile (char *src, char *dest)
  907. {
  908.     int        in, out;
  909.     int        remaining, count;
  910.     char    buf[4096];
  911.     
  912.     printf ("%s to %s\n", src, dest);
  913.  
  914.     in = SafeOpenRead (src);
  915.     remaining = filelength (in);
  916.     
  917.     CreatePath (dest);
  918.     out = SafeOpenWrite (dest);
  919.     
  920.     while (remaining)
  921.     {
  922.         if (remaining < sizeof(buf))
  923.             count = remaining;
  924.         else
  925.             count = sizeof(buf);
  926.         SafeRead (in, buf, count);
  927.         SafeWrite (out, buf, count);
  928.         remaining -= count;
  929.     }
  930.  
  931.     close (in);
  932.     close (out);    
  933. }
  934.  
  935.  
  936. /*
  937. ===========
  938. CopyFiles
  939. ===========
  940. */
  941. void CopyFiles (void)
  942. {
  943.     int        i, p;
  944.     char    srcdir[1024], destdir[1024];
  945.     char    srcfile[1024], destfile[1024];
  946.     int        copytype;
  947.     char    name[1024];
  948.     packheader_t    header;
  949.     int        dirlen;
  950.     int        blocknum;
  951.     unsigned short        crc;
  952.  
  953.     printf ("%3i unique precache_sounds\n", numsounds);
  954.     printf ("%3i unique precache_models\n", nummodels);
  955.     
  956.     copytype = 0;
  957.  
  958.     p = CheckParm ("-copy");
  959.     if (p && p < myargc-2)
  960.     {    // create a new directory tree
  961.         copytype = 1;
  962.  
  963.         strcpy (srcdir, myargv[p+1]);
  964.         strcpy (destdir, myargv[p+2]);
  965.         if (srcdir[strlen(srcdir)-1] != '/')
  966.             strcat (srcdir, "/");
  967.         if (destdir[strlen(destdir)-1] != '/')
  968.             strcat (destdir, "/");
  969.     }
  970.  
  971.     blocknum = 1;
  972.     p = CheckParm ("-pak2");
  973.     if (p && p <myargc-2)
  974.         blocknum = 2;
  975.     else
  976.         p = CheckParm ("-pak");
  977.     if (p && p < myargc-2)
  978.     {    // create a pak file
  979.         strcpy (srcdir, myargv[p+1]);
  980.         strcpy (destdir, myargv[p+2]);
  981.         if (srcdir[strlen(srcdir)-1] != '/')
  982.             strcat (srcdir, "/");
  983.         DefaultExtension (destdir, ".pak");
  984.  
  985.         pf = pfiles;
  986.         packhandle = SafeOpenWrite (destdir);
  987.         SafeWrite (packhandle, &header, sizeof(header));    
  988.         copytype = 2;
  989.     }
  990.     
  991.     if (!copytype)
  992.         return;
  993.                 
  994.     for (i=0 ; i<numsounds ; i++)
  995.     {
  996.         if (precache_sounds_block[i] != blocknum)
  997.             continue;
  998.         sprintf (name, "sound/%s", precache_sounds[i]);
  999.         sprintf (srcfile,"%s%s",srcdir, name);
  1000.         sprintf (destfile,"%s%s",destdir, name);
  1001.         if (copytype == 1)
  1002.             CopyFile (srcfile, destfile);
  1003.         else
  1004.             PackFile (srcfile, name);
  1005.     }
  1006.     for (i=0 ; i<nummodels ; i++)
  1007.     {
  1008.         if (precache_models_block[i] != blocknum)
  1009.             continue;
  1010.         sprintf (srcfile,"%s%s",srcdir, precache_models[i]);
  1011.         sprintf (destfile,"%s%s",destdir, precache_models[i]);
  1012.         if (copytype == 1)
  1013.             CopyFile (srcfile, destfile);
  1014.         else
  1015.             PackFile (srcfile, precache_models[i]);
  1016.     }
  1017.     for (i=0 ; i<numfiles ; i++)
  1018.     {
  1019.         if (precache_files_block[i] != blocknum)
  1020.             continue;
  1021.         sprintf (srcfile,"%s%s",srcdir, precache_files[i]);
  1022.         sprintf (destfile,"%s%s",destdir, precache_files[i]);
  1023.         if (copytype == 1)
  1024.             CopyFile (srcfile, destfile);
  1025.         else
  1026.             PackFile (srcfile, precache_files[i]);
  1027.     }
  1028.     
  1029.     if (copytype == 2)
  1030.     {
  1031.         header.id[0] = 'P';
  1032.         header.id[1] = 'A';
  1033.         header.id[2] = 'C';
  1034.         header.id[3] = 'K';
  1035.         dirlen = (byte *)pf - (byte *)pfiles;
  1036.         header.dirofs = LittleLong(lseek (packhandle, 0, SEEK_CUR));
  1037.         header.dirlen = LittleLong(dirlen);
  1038.         
  1039.         SafeWrite (packhandle, pfiles, dirlen);
  1040.     
  1041.         lseek (packhandle, 0, SEEK_SET);
  1042.         SafeWrite (packhandle, &header, sizeof(header));
  1043.         close (packhandle);    
  1044.     
  1045.     // do a crc of the file
  1046.         CRC_Init (&crc);
  1047.         for (i=0 ; i<dirlen ; i++)
  1048.             CRC_ProcessByte (&crc, ((byte *)pfiles)[i]);
  1049.     
  1050.         i = pf - pfiles;
  1051.         printf ("%i files packed in %i bytes (%i crc)\n",i, packbytes, crc);
  1052.     }
  1053. }
  1054.  
  1055. //============================================================================
  1056.  
  1057. /*
  1058. ============
  1059. main
  1060. ============
  1061. */
  1062. void main (int argc, char **argv)
  1063. {
  1064.     char    *src;
  1065.     char    *src2;
  1066.     char    filename[1024];
  1067.     int        p, crc;
  1068.     char    sourcedir[1024];
  1069.    time_t start;
  1070.  
  1071.     myargc = argc;
  1072.     myargv = argv;
  1073.  
  1074.     if ( CheckParm ("-?") || CheckParm ("-help"))
  1075.     {
  1076.         printf ("qcc looks for progs.src in the current directory.\n");
  1077.         printf ("to look in a different directory: qcc -src <directory>\n");
  1078.         printf ("to build a clean data tree: qcc -copy <srcdir> <destdir>\n");
  1079.         printf ("to build a clean pak file: qcc -pak <srcdir> <packfile>\n");
  1080.         printf ("to bsp all bmodels: qcc -bspmodels <gamedir>\n");
  1081.         return;
  1082.     }
  1083.  
  1084.     p = CheckParm ("-src");
  1085.     if (p && p < argc-1 )
  1086.     {
  1087.         strcpy (sourcedir, argv[p+1]);
  1088.         strcat (sourcedir, "/");
  1089.         printf ("Source directory: %s\n", sourcedir);
  1090.     }
  1091.     else
  1092.         strcpy (sourcedir, "");
  1093.  
  1094.     InitData ();
  1095.  
  1096.     sprintf (filename, "%sprogs.src", sourcedir);
  1097.     LoadFile (filename, (void *)&src);
  1098.  
  1099.     src = COM_Parse (src);
  1100.     if (!src)
  1101.         Error ("No destination filename.  qcc -help for info.\n");
  1102.     strcpy (destfile, com_token);
  1103.     printf ("outputfile: %s\n", destfile);
  1104.  
  1105.     start = time(NULL);
  1106.     pr_dumpasm = false;
  1107.  
  1108.     PR_BeginCompilation (malloc (0x100000), 0x100000);
  1109.  
  1110. // compile all the files
  1111.     do
  1112.     {
  1113.         src = COM_Parse(src);
  1114.         if (!src)
  1115.             break;
  1116.         sprintf (filename, "%s%s", sourcedir, com_token);
  1117.         printf ("compiling %s\n", filename);
  1118.         LoadFile (filename, (void *)&src2);
  1119.  
  1120.         if (!PR_CompileFile (src2, filename) )
  1121.             exit (1);
  1122.  
  1123.     } while (1);
  1124.  
  1125.     if (!PR_FinishCompilation ())
  1126.         Error ("compilation errors");
  1127.  
  1128.     p = CheckParm ("-asm");
  1129.     if (p)
  1130.     {
  1131.         for (p++ ; p < argc ; p++)
  1132.         {
  1133.             if (argv[p][0] == '-')
  1134.                 break;
  1135.             PrintFunction (argv[p]);
  1136.         }
  1137.     }
  1138.  
  1139. // write progdefs.h
  1140.    crc = PR_WriteProgdefs ("progdefs.h");
  1141.  
  1142. // write data file
  1143.     WriteData (crc);
  1144.  
  1145. // regenerate bmodels if -bspmodels
  1146.     BspModels ();
  1147.  
  1148. // report / copy the data files
  1149.     CopyFiles ();
  1150.   printf("Finished in %lu seconds\n", time(NULL) - start);
  1151. }
  1152.  
  1153.